package com.sicnu.gateway.filters;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Component
public class LoggingFilter extends AbstractGatewayFilterFactory<LoggingFilter.Config> {

    public LoggingFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            if (!config.isEnabled()) {
                return chain.filter(exchange);
            }

            // 记录请求信息
            System.out.println("\n=== 网关请求 ===");
            System.out.println("路径: " + exchange.getRequest().getPath());
            System.out.println("方法: " + exchange.getRequest().getMethod());
            System.out.println("头信息: " + exchange.getRequest().getHeaders());
            System.out.println("处理后Content-Type: " +
                    exchange.getRequest().getHeaders().getFirst("Content-Type"));
            System.out.println("请求体长度: " +
                    exchange.getRequest().getHeaders().getContentLength());

            // 记录请求体（如果启用）
            if (config.isLogBody()) {
                return DataBufferUtils.join(exchange.getRequest().getBody())
                        .flatMap(dataBuffer -> {
                            byte[] bytes = new byte[dataBuffer.readableByteCount()];
                            dataBuffer.read(bytes);
                            DataBufferUtils.release(dataBuffer);
                            String body = new String(bytes, StandardCharsets.UTF_8);
                            System.out.println("请求体内容: " + body);

                            // 重新包装请求
                            return chain.filter(exchange.mutate().request(
                                    new ServerHttpRequestDecorator(exchange.getRequest()) {
                                        @Override
                                        public Flux<DataBuffer> getBody() {
                                            return Flux.just(exchange.getResponse()
                                                    .bufferFactory().wrap(bytes));
                                        }
                                    }).build());
                        });
            }

            return chain.filter(exchange)
                    .then(Mono.fromRunnable(() -> {
                        // 记录响应信息
                        System.out.println("\n=== 网关响应 ===");
                        System.out.println("状态码: " + exchange.getResponse().getStatusCode());
                        System.out.println("响应头: " + exchange.getResponse().getHeaders());
                    }));
        };
    }

    public static class Config {
        private boolean enabled = true;
        private boolean logBody = false;

        // getters and setters
        public boolean isEnabled() { return enabled; }
        public void setEnabled(boolean enabled) { this.enabled = enabled; }
        public boolean isLogBody() { return logBody; }
        public void setLogBody(boolean logBody) { this.logBody = logBody; }
    }
}